home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume7 / dirstack.csh < prev    next >
Encoding:
Internet Message Format  |  1987-01-18  |  45.3 KB

  1. Subject:  v07i095:  CSH tools for directory stacks
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: pyrbos!gsg!lew (Paul Lew)
  6. Mod.sources: Volume 7, Issue 95
  7. Archive-name: dirstack.csh
  8.  
  9. This is a set of tool to manipulate Csh directory stacks.  It helps
  10. bad typists a lot and also benefits people who deal with a lot of
  11. directories.  I rarely type full pathnames after I started using it.
  12.  
  13. To try it out, type: source shdir.make, this will define some alias
  14. for you to use.  Type 's' and see what happens.
  15.  
  16. To install it, type:     shdir.make.
  17. Man page is in:          shdir.man.
  18.  
  19. comments to: decvax!gsg!lew
  20. ------------------------------Cut Here---------------------------------
  21. #! /bin/sh
  22. # This is a shell archive, meaning:
  23. # 1. Remove everything above the #! /bin/sh line.
  24. # 2. Save the resulting text in a file.
  25. # 3. Execute the file with /bin/sh (not csh) to create the files:
  26. #    shdir.make
  27. #    shdir.man
  28. #    restdir
  29. #    lsdir
  30. #    useshdir
  31. #    shdir.c
  32. export PATH; PATH=/bin:$PATH
  33. echo shar: extracting "'shdir.make'" '(6310 characters)'
  34. if test -f 'shdir.make'
  35. then
  36.     echo shar: will not over-write existing file "'shdir.make'"
  37. else
  38. sed 's/^X//' << \SHAR_EOF > 'shdir.make'
  39. X#! /bin/csh -f
  40. X#
  41. X#-    shdir.make - Directory stack installation script
  42. X#-
  43. X#-    To try out the function of shdir, use csh  "source" command to
  44. X#-    invoke this program since some aliases will need to be defined
  45. X#-    in your current environment.
  46. X#-
  47. X#-    Change the mode to execute and  then execute it  will cause it
  48. X#-    to be installed.
  49. X#-
  50. X#    Author:        Paul Lew, General Systems Group, Salem, NH
  51. X#    Last update:    10/14/86  02:26 PM
  52. X#
  53. X#if ( "${user}" == "lew" ) goto end
  54. X#---------------------------------------------------------------#
  55. X#    If invoked from csh "source" command, install locally    #
  56. X#    else install globally and update .login, .cshrc, and    #
  57. X#    .logout file.                        #
  58. X#---------------------------------------------------------------#
  59. Xif ( $?0 ) goto install
  60. X#---------------------------------------------------------------#
  61. X#           Compile shdir.c first            #
  62. X#---------------------------------------------------------------#
  63. Xif ( ! -e "shdir" ) then
  64. X    if ( ! -e shdir.c ) then
  65. X        echo "...File shdir.c missing, aborted..."
  66. X        goto end
  67. X        endif
  68. X    echo -n "...Compiling shdir.c "
  69. X    cc -s -o shdir shdir.c -ltermcap
  70. X    echo "done..."
  71. X    endif
  72. X#---------------------------------------------------------------#
  73. X#    Make sure all the required files are there        #
  74. X#---------------------------------------------------------------#
  75. Xforeach fname (restdir lsdir shdir useshdir)
  76. X    if ( ! -e ${fname} ) then
  77. X        echo "...${fname} not in directory ${cwd}, aborted..."
  78. X        goto end
  79. X        endif
  80. X    end
  81. X#---------------------------------------------------------------#
  82. X#        Define aliases in the current shell            #
  83. X#---------------------------------------------------------------#
  84. Xforeach aname (lsdir po s to)
  85. X    @ achar = `alias ${aname} | wc -c`
  86. X    if ( ${achar} > 0 ) echo "...alias ${aname} will be redefined..."
  87. X    end
  88. Xunset aname achar
  89. Xalias    lsdir    source ${cwd}/lsdir
  90. Xalias    po    'popd +\!* > /dev/null; shdir `dirs`'
  91. Xalias    s    ${cwd}'/shdir -s\!* `dirs` ;if ( ${status} ) pushd +${status} > /dev/null'
  92. Xalias    to    'pushd \!* > /dev/null ; '"${cwd}"'/shdir `dirs`'
  93. X#---------------------------------------------------------------#
  94. X#      Make a set of directory stack to demo            #
  95. X#---------------------------------------------------------------#
  96. Xset dirs = (`dirs`)
  97. Xif ( ${#dirs} < 3 ) then
  98. X    cd /usr/lib/uucp
  99. X    foreach x (/usr/spool/uucp /usr/spool/uucppublic /etc ${cwd})
  100. X        pushd $x > /dev/null
  101. X        end
  102. X    unset x
  103. X    endif
  104. X#---------------------------------------------------------------#
  105. X#    Modify TERMCAP so he/she will see the result        #
  106. X#---------------------------------------------------------------#
  107. Xswitch ( "${TERM}" )
  108. X    case vt100:
  109. X    case vt102:
  110. X    case vt125:
  111. X    case vt220:
  112. X    case vt240:
  113. X    case wy75:
  114. X        set noglob
  115. X        eval `tset -Q -s`
  116. X        unset noglob
  117. X        set tc = ('jjkkllmmqqxx' '\E(B' '\E(0')
  118. X        foreach te (ac ae as)
  119. X        echo "${TERMCAP}" | fgrep -s ":${te}"
  120. X        if ( ${status} == 1 ) then
  121. X            echo "...${te} added to TERMCAP..."
  122. X            setenv TERMCAP "${TERMCAP}${te}=${tc[1]}:"
  123. X            endif
  124. X        shift tc
  125. X        end
  126. X        breaksw
  127. X    default:
  128. X    endsw
  129. X#---------------------------------------------------------------#
  130. X#             Give a little hint                #
  131. X#---------------------------------------------------------------#
  132. Xcat << cat_eof
  133. X...Now type 's' and move to the directory you want by pressing space bar....
  134. Xcat_eof
  135. Xgoto end
  136. X
  137. X#---------------------------------------------------------------#
  138. X#        Final installation starts here            #
  139. X#---------------------------------------------------------------#
  140. Xinstall:
  141. Xcat << cat_eof
  142. X       **************** GENERAL INFORMATION ****************
  143. X
  144. XThis is the final installation procedure.  It will move all the
  145. Xexecutables to proper directory and also modify your .login, and
  146. X.logout file so that directory stack will preserve across logins.
  147. XYour .cshrc will also be modified to define aliases.
  148. X
  149. XThe defualt place to store the executables is: /usr/local/bin so that
  150. Xit can be shared among users.  Press return on to the question below
  151. Xif you like to use the default.
  152. X
  153. Xcat_eof
  154. Xecho -n "Where do you want to place executables in your system? "
  155. Xset dir = "$<"
  156. Xif ( "${dir}" == "" ) set dir = '/usr/local/bin'
  157. Xif ( ! -d "${dir}" ) then
  158. X    mkdir "${dir}"
  159. X    if ( ! -d "${dir}" ) then
  160. X        echo "...${dir} is not a valid directory, aborted..."
  161. X        goto end
  162. X        endif
  163. X    endif
  164. X#---------------------------------------------------------------#
  165. X#     Check if dir specified is in the search path        #
  166. X#---------------------------------------------------------------#
  167. Xunset inpath
  168. Xforeach cpath (${path})
  169. X    if ( "${cpath}" == "${dir}" ) then
  170. X        set inpath
  171. X        break
  172. X        endif
  173. X    end
  174. Xif ( ! ${?inpath} ) then
  175. X    echo "...Warning: ${dir} not defined in your search path..."
  176. X    endif
  177. Xunset inpath cpath
  178. X#---------------------------------------------------------------#
  179. X#      Move script to the executables directory        #
  180. X#---------------------------------------------------------------#
  181. Xforeach fname (restdir lsdir shdir useshdir)
  182. X    if ( -e "${dir}/${fname}" ) then
  183. X        echo "...${dir}/${fname} already exist..."
  184. X        continue
  185. X        endif
  186. X    if ( ! -e ${fname} ) then
  187. X        echo "...${fname} not in directory ${cwd}, aborted..."
  188. X        goto end
  189. X        endif
  190. X    if ( ${cwd} == "${dir}" ) continue
  191. X    if ( -e "${dir}/${fname}" ) then
  192. X        echo "...${dir}/${fname} already exist..."
  193. X    else
  194. X        /bin/mv ${fname} "${dir}"
  195. X        endif
  196. X    end
  197. Xsed -e "s:source /usr/local/bin:source ${dir}:" < ${dir}/lsdir > /tmp/lsdir$$
  198. X/bin/mv -f /tmp/lsdir$$ ${dir}/lsdir
  199. X/bin/chmod a+rx "${dir}/useshdir"
  200. X/bin/chmod a+r-x "${dir}"/{restdir,lsdir}
  201. X#---------------------------------------------------------------#
  202. X#      Modify .cshrc, .logout to install for my account        #
  203. X#---------------------------------------------------------------#
  204. X${dir}/useshdir ${dir}
  205. Xcat << cat_eof
  206. X--------------------------------------------------------------------
  207. XIf anyone else in your system would like to use shdir, he/she only
  208. Xneed to execute script: useshdir.
  209. X
  210. XIf you like to have VT100 graphic characters to draw the box, add the
  211. Xfollowing to your termcap entry after you verify it does support these
  212. Xfeatures:
  213. X
  214. X    :ac=jjkkllmmqqxx:    #alternate graphic characters
  215. X    :as=\E(0:        #alternate set start
  216. X    :ae=\E(B:        #alternate set end
  217. X
  218. X   ******** The installation is now complete, have fun!! ********
  219. Xcat_eof
  220. X#---------------------------------------------------------------#
  221. X#              Exit here                #
  222. X#---------------------------------------------------------------#
  223. Xunset added msg
  224. Xend:
  225. SHAR_EOF
  226. if test 6310 -ne "`wc -c < 'shdir.make'`"
  227. then
  228.     echo shar: error transmitting "'shdir.make'" '(should have been 6310 characters)'
  229. fi
  230. chmod +x 'shdir.make'
  231. fi # end of overwriting check
  232. echo shar: extracting "'shdir.man'" '(4868 characters)'
  233. if test -f 'shdir.man'
  234. then
  235.     echo shar: will not over-write existing file "'shdir.man'"
  236. else
  237. sed 's/^X//' << \SHAR_EOF > 'shdir.man'
  238. X.TH shdir 1-gsg "14 Oct 1986"
  239. X.SH NAME
  240. Xshdir, lsdir - C shell directory manipulation package
  241. X.SH SYNOPSIS
  242. XMost of the followings are C-shell aliases:
  243. X.IP "s                  switch directory"
  244. X.IP "to [dir]           push to a new directory"
  245. X.IP "po [n]             pop out an old directory"
  246. X.IP "lsdir [filename]   load/save directory stack"
  247. X.SH DESCRIPTION
  248. X.I Shdir
  249. Xis actually a set of C program, shell scripts and aliases which
  250. Xwill assist you to use BSD directory stack feature easily.
  251. X.PP
  252. XThe main program "shdir" is a C program which take C-shell dirs output
  253. Xand display it graphically on the output with VT100 graphic chars.  It
  254. Xalso allow you to move the cursor to the desired directory and change
  255. Xto it with one keystroke.  The following is a list of commands to
  256. Xshdir:
  257. X.sp
  258. X.DS 
  259. X    space, j, J, l, L       move cursor down one line
  260. X    backspace, k, K, h, H   move cursor up one line
  261. X    n, p                    search for next/previous string
  262. X    0-9                     go to the next 0-9
  263. X    return                  select the entry
  264. X.sp
  265. X    Options to shdir:
  266. X.sp
  267. X    -s     or               select mode
  268. X    -sxxx                   search string xxx in dir stack
  269. X    -r                      use scroll if possible
  270. X    -bx                     set box style to x (see below)
  271. X    -v                      display version number
  272. X.DE
  273. X.PP
  274. XOption '-s' tells shdir to enter select mode, i.e., displays directory
  275. Xstack on the tube and allows user to select an entry.  If any argument
  276. Xis supplied after the -s option to shdir,  it will be used as the
  277. Xstring to search thru the directory stack.  If exactly one entry
  278. Xmatches, shdir will echo that directory name and exit without
  279. Xdisplaying the directory stack.  If more than one entry found, the
  280. Xstack will be displayed on the tube with the cursor at the first entry
  281. Xcontaining the string, type 'n' or 'p' will find the next/previous
  282. Xmatch entry.
  283. X.PP
  284. XAn option '-r' to shdir will make the stack rotate on the tube, this
  285. Xway you will not have to imagine what the stack looks like after it
  286. Xrotates.  However, this feature can not be done by termcap
  287. Xdescription, and currently only works for VT100 type of terminals.
  288. X.PP
  289. XShdir also allows you to choose your own box style by supplying -b
  290. Xoption.  If the char after 'b' is 'h', shdir will try to use highlite
  291. Xblanks for the box. If it is 'r', shdir will use reverse-video blanks
  292. Xfor the box.  If it is 'g', shdir will use graphical chars for the
  293. Xbox.  The default style sequence is (1) graphic chars, (2) highlite
  294. Xblanks, (3) reverse video blanks, and (4) regular dashes.  If the
  295. Xstyle you selected does not exist for your terminal in the termcap
  296. Xdatabase, the next one in the style list will be used.
  297. X.PP
  298. XLsdir is a script which allow you to switch the entire directory stack
  299. Xto a new environment.  For example, you may work on two projects, one
  300. Xproject uses 8 directories and the other projects uses 5 different
  301. Xdirectories.
  302. X.PP
  303. X.I s,
  304. X.I to,
  305. Xand
  306. X.I po
  307. Xare actually aliases, it means Switch to a new directory, push TO a new
  308. Xdirectory, and POp up a given entry on the stack.
  309. XYou may want to change them to whatever you like.
  310. XThe definition looks like:
  311. X.sp
  312. X.DS
  313. X    alias lsdir 'source ${dir}/lsdir'
  314. X    alias po    'popd +\\!* > /dev/null; shdir \`dirs\`'
  315. X    alias s     'shdir -s\\!* \`dirs\` ; \\
  316. X                if (${status}) pushd +${status}>/dev/null'
  317. X    alias to    'pushd \\!* > /dev/null ; shdir \`dirs\`'
  318. X.DE
  319. X.PP
  320. XScript useshdir will modify your (1) .login to restore previously
  321. Xsaved directory stack, so the environment can be preserved. (2) .cshrc
  322. Xto define aliases (lsdir, po, s, to), so shdir can be invoke. (3) .logout
  323. Xto save directory stack to a file.
  324. X.PP
  325. X.SH FILES
  326. X.br
  327. X/usr/local/bin/restdir, /usr/local/bin/lsdir, /usr/local/bin/useshdir
  328. X.SH AUTHOR
  329. XPaul Lew
  330. X.br
  331. XGeneral Systems Group, Salem NH
  332. X.SH BUGS
  333. XThis version uses termcap "ac" feature to draw graphic box. It may not
  334. Xexist in your /etc/termcap file.
  335. X.PP
  336. XThere is output flushing problem when run shdir over Enet, sometimes
  337. Xthe output did not seem to get flushed before switching to RAW mode.
  338. XCurrent resolution is to add a one second delay if stdout is a
  339. Xpseudo-terminal. Better solution should be investigated.
  340. X.PP
  341. XIf you select scrolling option (-r), shdir will poll the terminal for
  342. Xits cursor position in order to decide the proper scrolling region.
  343. XIt ASSUMED the return device cursor status report (DSR) to be string
  344. Xlike: "ESC [ line; column R", this will only works for VT100 type
  345. Xterminals.
  346. X.PP
  347. XThis program will not work if you have a directory name contains space(s).
  348. XThis is because the output of dirs command uses spaces to separate
  349. Xdirectory names.
  350. X.PP
  351. XShdir uses tabs to fill the end of line, this may cause little problem
  352. Xon your terminal it terminal tab stops is not 8.
  353. X.PP
  354. XFor hackers: How about add features to termcap/terminfo so that all
  355. Xthe  (DSR) operations can be done?
  356. SHAR_EOF
  357. if test 4868 -ne "`wc -c < 'shdir.man'`"
  358. then
  359.     echo shar: error transmitting "'shdir.man'" '(should have been 4868 characters)'
  360. fi
  361. fi # end of overwriting check
  362. echo shar: extracting "'restdir'" '(649 characters)'
  363. if test -f 'restdir'
  364. then
  365.     echo shar: will not over-write existing file "'restdir'"
  366. else
  367. sed 's/^X//' << \SHAR_EOF > 'restdir'
  368. X#! /bin/csh -f
  369. X#
  370. X#    Shell script to restore directory stack (this file should be sourced)
  371. X#
  372. X#    Author:        Paul Lew, General Systems Group, Inc.
  373. X#    Created at:    01/03/86
  374. X#    Last update:    10/08/86  05:07 PM
  375. X#
  376. Xif ( $?0 ) then
  377. X    echo "...You should source this program, not execute it..."
  378. X    goto end
  379. X    endif
  380. Xif ( ! ${?SAVED_WD} ) setenv SAVED_WD ~/saved_wd
  381. Xif ( ! ${?filename} ) set filename = ${SAVED_WD}/cwd.wd
  382. Xset _dirlist = `cat ${filename}`
  383. Xset _dirs
  384. Xforeach _dir (${_dirlist})            #reverse directory stack
  385. X    set _dirs = (${_dir} ${_dirs})
  386. X    end
  387. Xchdir ${_dirs[1]}
  388. Xshift _dirs
  389. Xforeach _dir (${_dirs})
  390. X    pushd ${_dir} > /dev/null
  391. X    end
  392. Xunset _dirlist _dir _dirs
  393. Xend:
  394. SHAR_EOF
  395. if test 649 -ne "`wc -c < 'restdir'`"
  396. then
  397.     echo shar: error transmitting "'restdir'" '(should have been 649 characters)'
  398. fi
  399. fi # end of overwriting check
  400. echo shar: extracting "'lsdir'" '(2340 characters)'
  401. if test -f 'lsdir'
  402. then
  403.     echo shar: will not over-write existing file "'lsdir'"
  404. else
  405. sed 's/^X//' << \SHAR_EOF > 'lsdir'
  406. X#! /bin/csh -f
  407. X#
  408. X#    Shell script to load/save current directory stack from/to a file
  409. X#
  410. X#    Author:        Paul Lew
  411. X#    Created at:    02/28/86  12:43
  412. X#    Last update:    10/08/86  04:48 PM
  413. X#
  414. X#    Usage:    source lsdir <CR>    -- must be sourced
  415. X#
  416. Xif ( $?0 ) then
  417. X    echo "...You should source this program, not execute it..."
  418. X    goto end
  419. X    endif
  420. X#---------------------------------------------------------------#
  421. X#             Variable Declarations            #
  422. X#---------------------------------------------------------------#
  423. Xif ( ! ${?SAVED_WD} ) setenv SAVED_WD ~/saved_wd
  424. Xunset load_dirs
  425. Xset fname = ""
  426. Xecho -n "Enter S/L/D for save/load/directory: "
  427. Xswitch ( "$<" )
  428. X    case [lL]:
  429. X        set load_dirs
  430. X        set opt = 'load'
  431. X        breaksw
  432. X    case [sS]:
  433. X        set opt = 'save'
  434. X        breaksw
  435. X    case [dD]:
  436. X        ls -l ${SAVED_WD}/*.wd | less
  437. X        while ( 1 )
  438. X            echo -n "File to see (no extension): "
  439. X            set fname = "$<"
  440. X            if ( ${fname} == "" ) goto end
  441. X            cat ${SAVED_WD}/${fname}.wd | shdir
  442. X            end
  443. X    default:
  444. X        goto end
  445. X    endsw
  446. X#---------------------------------------------------------------#
  447. X#    Get filename from terminal and make sure it exists    #
  448. X#---------------------------------------------------------------#
  449. Xwhile ( "${fname}" == "" )
  450. X    echo -n "File to ${opt}: "
  451. X    set fname = "$<"
  452. X    if ( "${fname}" == "" ) continue
  453. X    if ( "${fname:t}" != "${fname}" ) then
  454. X        echo -n "No path allowed, "
  455. X        set fname = ''
  456. X        endif
  457. X    set filename = "${SAVED_WD}/${fname}.wd"
  458. X    if ( ${?load_dirs} ) then
  459. X        if ( ! -e "${filename}" ) then
  460. X            echo -n "File [${filename}] does not exist, "
  461. X            set fname = ''
  462. X            endif
  463. X        endif
  464. X    end
  465. X#---------------------------------------------------------------#
  466. X#            Process request                #
  467. X#---------------------------------------------------------------#
  468. Xif ( ${?load_dirs} ) then
  469. X    set curdir = `dirs`
  470. X    echo "Old directory stack looks like:"
  471. X    shdir ${curdir}
  472. X    @ dir_count = ${#curdir} - 1
  473. X    repeat ${dir_count} popd > /dev/null
  474. X    source /usr/local/bin/restdir
  475. X    echo "New directory stack looks like:"
  476. X    shdir `dirs`
  477. Xelse
  478. X    if ( -e ${filename} ) then
  479. X        cat ${filename} | shdir
  480. X        echo -n "Old file listed above, override? [y/n]: "
  481. X        if ( "$<" != "y" ) goto end
  482. X        endif
  483. X    dirs > ${filename}
  484. X    endif
  485. X#---------------------------------------------------------------#
  486. X#        Clean up and exit here...            #
  487. X#---------------------------------------------------------------#
  488. Xend:
  489. X    unset filename fname load_dirs dir_count curdir
  490. SHAR_EOF
  491. if test 2340 -ne "`wc -c < 'lsdir'`"
  492. then
  493.     echo shar: error transmitting "'lsdir'" '(should have been 2340 characters)'
  494. fi
  495. fi # end of overwriting check
  496. echo shar: extracting "'useshdir'" '(3676 characters)'
  497. if test -f 'useshdir'
  498. then
  499.     echo shar: will not over-write existing file "'useshdir'"
  500. else
  501. sed 's/^X//' << \SHAR_EOF > 'useshdir'
  502. X#! /bin/csh -f
  503. X#
  504. X#-    useshdir - Update .login, .logout, and .cshrc to install shdir
  505. X#-
  506. X#-    This program will modify your .cshrc, .login, and .logout files
  507. X#-    so that: (1) proper aliases will be defined. (2) directory stack
  508. X#-    will be saved on logout and restored on login.
  509. X#-
  510. X#    Author:        Paul Lew, General Systems Group, Salem, NH
  511. X#    Created at:    10/08/86  12:23 PM
  512. X#    Last update:    10/14/86  02:28 PM
  513. X#
  514. X#-    Usage:    useshdir dirname <CR>
  515. X#-
  516. X#-    where: dirname is the directory where the shdir stored.
  517. X#
  518. Xset tmpfile = "/tmp/shdir$$.setup"
  519. X#---------------------------------------------------------------#
  520. X#       Find shdir directory if not specified        #
  521. X#---------------------------------------------------------------#
  522. Xset dir = "$1"
  523. Xif ( "${dir}" == "" ) set dir = '/usr/local/bin'
  524. Xwhile (1)
  525. X    if ( -e "${dir}/shdir" ) break
  526. X    echo -n "Which directory did the shdir stored? "
  527. X    set dir = "$<"
  528. X    end
  529. X#---------------------------------------------------------------#
  530. X#        Get Box style choice from the user            #
  531. X#---------------------------------------------------------------#
  532. Xcat << cat_eof
  533. X
  534. Xshdir can display the box in 3 styles (only if your terminal can
  535. Xsupport the selected feature, i.e., proper entries in termcap
  536. Xdatabase):
  537. X
  538. X    <1> special graphical character set for lines (default)
  539. X    <2> reverse video blanks
  540. X    <3> hightlighted blanks
  541. X
  542. Xcat_eof
  543. Xecho -n "Please make a choice: [1-3]: "
  544. Xswitch ( "$<" )
  545. X    case 2:
  546. X        set shdir = (shdir -br)
  547. X        breaksw
  548. X    case 3:
  549. X        set shdir = (shdir -bh)
  550. X        breaksw
  551. X    case 1:
  552. X    default:
  553. X        set shdir = (shdir)
  554. X    endsw
  555. X#---------------------------------------------------------------#
  556. X#        Add aliases to .cshrc file            #
  557. X#---------------------------------------------------------------#
  558. Xset msg = "Directory stack operation aliases"
  559. X@ added = 0
  560. Xif ( -e ~/.cshrc ) @ added = `grep "${msg}" ~/.cshrc | wc -l`
  561. Xif ( ${added} == 0 ) then
  562. X    cat > ${tmpfile} << cat_eof
  563. X#
  564. X# ${msg}  (Added: `date`)
  565. X#
  566. Xalias    lsdir    'source ${dir}/lsdir'
  567. Xalias    po    'popd +\!* > /dev/null; '"${shdir}"' \`dirs\`'
  568. Xalias    s    ${shdir} '-s\!* \`dirs\` ;if ( \${status} ) pushd +\${status} > /dev/null'
  569. Xalias    to    'pushd \!* > /dev/null ; '"${shdir}"' \`dirs\`'
  570. Xcat_eof
  571. X    echo ''
  572. X    cat ${tmpfile}
  573. X    echo ''
  574. X    echo -n "Do you want to add these aliases to .cshrc file? [y/n]: "
  575. X    if ( "$<" == "y") cat ${tmpfile} >> ~/.cshrc
  576. X    endif
  577. X#---------------------------------------------------------------#
  578. X#       Update directory stack save in .logout        #
  579. X#---------------------------------------------------------------#
  580. Xif ( ! -e ~/saved_wd ) mkdir ~/saved_wd
  581. Xset msg = "save directory stack for next login"
  582. X@ added = 0
  583. Xif ( -e ~/.logout ) @ added = `grep "${msg}" ~/.logout | wc -l`
  584. Xif ( ${added} == 0 ) then
  585. X    echo "# ${msg}" > ${tmpfile}
  586. X    echo 'dirs > ~/saved_wd/cwd.wd' >> ${tmpfile}
  587. X    echo ''
  588. X    cat ${tmpfile}
  589. X    echo ''
  590. X    echo -n "Do you want to add the line above to .logout file? [y/n]: "
  591. X    if ( "$<" == "y") cat ${tmpfile} >> ~/.logout
  592. X    endif
  593. X#---------------------------------------------------------------#
  594. X#        Add restore directory in .login            #
  595. X#---------------------------------------------------------------#
  596. Xset msg = "restore last working directory stacks"
  597. X@ added = 0
  598. Xif ( -e ~/.login ) @ added = `grep "${msg}" ~/.login | wc -l`
  599. X#
  600. Xif ( ${added} == 0 ) then
  601. X    cat > ${tmpfile} << cat_eof
  602. X# ${msg}
  603. Xsource ${dir}/restdir
  604. X${shdir} \`dirs\`
  605. Xcat_eof
  606. X#
  607. X    echo ''
  608. X    cat ${tmpfile}
  609. X    echo ''
  610. X    echo -n "Do you want to add above 3 lines to .login file? [y/n]: "
  611. X    if ( "$<" == "y") cat ${tmpfile} >> ~/.login
  612. X    endif
  613. X#---------------------------------------------------------------#
  614. X#                Exit here                #
  615. X#---------------------------------------------------------------#
  616. Xend:
  617. X/bin/rm -f ${tmpfile}
  618. Xunset tmpfile dir msg added shdir
  619. SHAR_EOF
  620. if test 3676 -ne "`wc -c < 'useshdir'`"
  621. then
  622.     echo shar: error transmitting "'useshdir'" '(should have been 3676 characters)'
  623. fi
  624. chmod +x 'useshdir'
  625. fi # end of overwriting check
  626. echo shar: extracting "'shdir.c'" '(23978 characters)'
  627. if test -f 'shdir.c'
  628. then
  629.     echo shar: will not over-write existing file "'shdir.c'"
  630. else
  631. sed 's/^X//' << \SHAR_EOF > 'shdir.c'
  632. X/**************************************************************************
  633. X*
  634. X* File name:    shdir.c
  635. X*
  636. X* Author:    Paul Lew, General Systems Group, Inc. Salem, NH
  637. X* Created at:    02/17/86  04:39 PM
  638. X*
  639. X* Description:    This program will take input argument from C shell directory
  640. X*        stack and display on screen.  User can optionally select a
  641. X*        directory to connect to.
  642. X*    
  643. X* Environment:    4.2 BSD Unix (under Pyramid OSx 2.5)
  644. X*
  645. X* Usage:    shdir [-r] [-sxxx] [-bh] [-br] [-bd] [-v] `dirs` <CR>
  646. X*        where:
  647. X*            -v    display version number
  648. X*            -bh    use highlighted space for box
  649. X*            -br    use reverse video space for box
  650. X*            -bd    use dash char for box
  651. X*            -r    use scroll if terminal support
  652. X*            -sxxx    select directory xxx. If xxx not found or
  653. X*                not specified, directory stack will be
  654. X*                displayed to allow for selection.
  655. X*
  656. X* Update History:
  657. X*
  658. X*      Date        Description                    By
  659. X*    --------    ------------------------------------------------    ---
  660. X*    02/17/86    Ver 1.0, Initial version                Lew
  661. X*    02/28/86    Ver 1.1, add h, k for going backwards            Lew
  662. X*    07/01/86    Ver 2.0, modify to work with termcap            Lew
  663. X*    10/06/86    Ver 2.1, port to VAX BSD 4.2                Lew
  664. X*    10/09/86    Ver 3.0, add scrolling capability            Lew
  665. X*    10/13/86    Ver 3.1, add different options for different box style    Lew
  666. X*    10/14/86    Ver 3.2, add string search feature            Lew
  667. X*
  668. X* Build:    cc -s -o shdir shdir.c -ltermcap
  669. X*
  670. X***************************************************************************/
  671. X#include    <stdio.h>
  672. X#include    <sgtty.h>
  673. X#include    <ctype.h>
  674. X#include    <strings.h>
  675. X#include    <sys/file.h>
  676. X
  677. X#define        YES    1
  678. X#define        NO    0
  679. X#define        EOS    '\0'            /* end of string */
  680. X#define        SPACE    ' '
  681. X#define        BS    '\010'
  682. X#define        ESC    '\033'
  683. X#define        RETURN    '\015'
  684. X#define        NEWLINE    '\012'
  685. X
  686. X#define    when        break; case
  687. X#define    otherwise    break;default
  688. X
  689. Xchar        *Version = "shdir Version 3.2  10/16/86  10:47 AM";
  690. Xchar        *Author =
  691. X         "Paul Lew, General Systems Group   UUCP: decvax!gsg!lew";
  692. X
  693. XFILE        *Termfp;        /* terminal file pointer */
  694. X
  695. X#define        MAXDIR    22        /* not over typical screen size */
  696. Xint        Maxdir = MAXDIR;    /* max # of directory to display */
  697. X
  698. X#define        MAXBAR    200
  699. X
  700. Xchar        Bar [MAXBAR];        /* vanilla bar */
  701. Xchar        Topbar [MAXBAR];    /* top bar string */
  702. Xchar        Botbar [MAXBAR];    /* bottom bar string */
  703. Xchar        Vbar [20];        /* vertical bar string */
  704. X
  705. Xchar        Tab [80];
  706. Xint        Ntab;
  707. Xchar        Stack [1024];
  708. Xchar        *Dirstack [MAXDIR];    /* pointers to directory entries */
  709. Xint        Arglen [MAXDIR];    /* lengths of each entry */
  710. Xint        Dircount = 0;
  711. Xint        Topsel = 0;        /* start selection index */
  712. X
  713. X/* Curpos_query is a string to be sent to VT100 to get current cursor
  714. X   position report.  There is no such field in termcap, you have to hack
  715. X   the routine for other terminals since they might have different report
  716. X   format */
  717. X
  718. Xchar        *Curpos_query = "\033[6n"; /* cursor position query */
  719. Xint        Line;            /* # of lines per screen */
  720. Xint        Fst_line = 0;        /* if %i specified Fst_line = 1 */
  721. X
  722. Xstruct    sgttyb    Scd;
  723. Xint        Sno = 1;        /* first entry start index */
  724. X
  725. Xint        Select = NO;        /* YES = select entry */
  726. Xint        Scroll = NO;        /* YES = use scroll feature if exist */
  727. Xint        Tabstop = 8;        /* default tab-stop */
  728. X
  729. Xchar        *Search_string = NULL;    /* select search string */
  730. Xint        Schlen = 0;        /* search string length */
  731. Xint        Str_total = 0;        /* total matched search string */
  732. Xint        Str_idx [MAXDIR];    /* string index */
  733. X
  734. X#define    BOX_REVERSE    1
  735. X#define    BOX_HIGHLITE    2
  736. X#define    BOX_GRAPH    3
  737. X#define    BOX_DASH    4
  738. X
  739. Xint        Boxstyle = BOX_GRAPH;    /* default box style */
  740. X
  741. Xstruct    tcap    {
  742. X    char        tc_id [3];    /* key for capability    */
  743. X    unsigned char    tc_delay;    /* # of msec to delay    */
  744. X    char        *tc_str;    /* ptr to Tc_str area    */
  745. X    unsigned char    tc_len;        /* length of tc_str    */
  746. X    };
  747. X
  748. Xstatic    char    Termcap [1024];
  749. Xstatic    char    Tstr [1024];        /* buffer for real escape sequence */
  750. Xstatic    char    *Tsp = Tstr;        /* pointer to be used by tgetstr */
  751. Xstatic    int    Tcap_count = 0;        /* # of entries extracted */
  752. X
  753. X/*---------------- You may want to modify the following ----------------*/
  754. X
  755. X#define        AC    0
  756. X#define        AE    1
  757. X#define        AS    2
  758. X#define        LE    3
  759. X#define        ND    4
  760. X#define        NL    5
  761. X#define        UP    6
  762. X#define        SR    7
  763. X#define        SC    8
  764. X#define        RC    9
  765. X#define        CS    10
  766. X#define        MR    11
  767. X#define        MD    12
  768. X#define        ME    13
  769. X#define        BAD    14
  770. X
  771. Xstatic    struct    tcap Tcap [] = {
  772. X        { "ac",    0, NULL, 0 },    /* alternate chars        */
  773. X        { "ae",    0, NULL, 0 },    /* exit alternate char set    */
  774. X        { "as",    0, NULL, 0 },    /* start alternate char set    */
  775. X        { "le", 0, NULL, 0 },    /* cursor left (CTRL H)        */
  776. X        { "nd", 0, NULL, 0 },    /* cursor right            */
  777. X        { "nl", 0, NULL, 0 },    /* cursor down (new line)    */
  778. X        { "up", 0, NULL, 0 },    /* cursor up            */
  779. X        { "sr", 0, NULL, 0 },    /* scroll reverse        */
  780. X        { "sc", 0, NULL, 0 },    /* save cursor position        */
  781. X        { "rc", 0, NULL, 0 },    /* restore cursor position    */
  782. X        { "cs", 0, NULL, 0 },    /* set cursor scroll range    */
  783. X        { "mr", 0, NULL, 0 },    /* mode reverse video        */
  784. X        { "md", 0, NULL, 0 },    /* mode dense (highlight)    */
  785. X        { "me", 0, NULL, 0 },    /* mode end (back to normal)    */
  786. X        {   "", 0, NULL, 0 }
  787. X    };
  788. X
  789. X#define    SAVE_CURSOR    fprintf (Termfp, "%s", Tcap[SC].tc_str)
  790. X#define    RESTORE_CURSOR    fprintf (Termfp, "%s", Tcap[RC].tc_str)
  791. X
  792. Xchar    *getenv(), *tgetstr(), *tgoto();
  793. Xchar    *cs_define(), get_ac();
  794. Xchar    *malloc();
  795. X
  796. X/*------------------------------------------------------------07/13/84--+
  797. X|                                    |
  798. X|        M a i n    R o u t i n e    S t a r t s    H e r e        |
  799. X|                                    |
  800. X+----------------------------------------------------------------------*/
  801. Xmain (argc, argv)
  802. Xint    argc;        /* number of argument passed        */
  803. Xchar    **argv;        /* pointer to argument list        */
  804. X    {
  805. X    register int    i, j;
  806. X    char        *top = "\t";    /* top of stack string */
  807. X    int        size;        /* longest string */
  808. X
  809. X    Termfp = fopen ("/dev/tty", "r+");
  810. X    if (proc_arg (argc, argv) == 1) size = make_argv ();
  811. X    else size = cp_ptr (argc, argv);
  812. X
  813. X    if (!Dircount) my_exit (0);
  814. X    if (Search_string) Topsel = search ();
  815. X
  816. X    Ntab = make_bar (size) / 8;
  817. X    fprintf (Termfp, "%s\n", Topbar);
  818. X
  819. X    if (Scroll) j = Topsel;
  820. X    else    {
  821. X        top = "   Top->";
  822. X        j = 0;
  823. X        }
  824. X
  825. X    for (i=0; i<Dircount; i++) {
  826. X        put_line (j, (j==0) ? top : "\t", "\n");
  827. X        if (++j >= Dircount) j = 0;
  828. X        }
  829. X
  830. X    fprintf (Termfp, "%s\n", Botbar); fflush (Termfp);
  831. X
  832. X    if (Select && Dircount > 1) {
  833. X        if (Tcap[UP].tc_len) my_exit (get_rdata ());
  834. X        else my_exit (get_data ());
  835. X        }
  836. X
  837. X    my_exit (0);
  838. X    }
  839. X
  840. X/*-------------------------------------------------------------07/02/86-+
  841. X|                                    |
  842. X|          make_bar : make all the graphical bar strings        |
  843. X|                                    |
  844. X+----------------------------------------------------------------------*/
  845. Xmake_bar (size)
  846. Xint    size;
  847. X    {
  848. X    register int    i;
  849. X    char        *p;
  850. X    char        hbar = get_ac('q');
  851. X
  852. X    size = ((size + 5)/Tabstop + 1) * Tabstop;
  853. X    for (i=0; i<size-1 && i<MAXBAR; i++)
  854. X        Bar[i] = hbar;        /* create bar string */
  855. X    Bar[i] = EOS;
  856. X
  857. X    switch (Boxstyle) {
  858. X        case BOX_GRAPH:
  859. X        if (Tcap[AC].tc_len) break;
  860. X        Boxstyle = BOX_HIGHLITE;
  861. X        case BOX_HIGHLITE:
  862. X        if (Tcap[MD].tc_len && Tcap[ME].tc_len) break;
  863. X        Boxstyle = BOX_REVERSE;
  864. X        case BOX_REVERSE:
  865. X        if (Tcap[MR].tc_len && Tcap[ME].tc_len) break;
  866. X        default:
  867. X        Boxstyle = BOX_DASH;
  868. X        }
  869. X
  870. X    if (Boxstyle == BOX_GRAPH) {
  871. X        sprintf (Topbar, "\015\t%s%c%s%c%s", Tcap[AS].tc_str,
  872. X             get_ac('l'), Bar, get_ac('k'), Tcap[AE].tc_str);
  873. X        sprintf (Vbar, "%s%c%s", Tcap[AS].tc_str, get_ac('x'),
  874. X             Tcap[AE].tc_str);
  875. X        sprintf (Botbar, "\t%s%c%s%c%s", Tcap[AS].tc_str,
  876. X             get_ac('m'), Bar, get_ac('j'), Tcap[AE].tc_str);
  877. X        }
  878. X    else if (Boxstyle == BOX_REVERSE || Boxstyle == BOX_HIGHLITE) {
  879. X        while (--i >= 0) Bar[i] = SPACE;
  880. X        p = Tcap [(Boxstyle == BOX_HIGHLITE) ? MD : MR].tc_str;
  881. X        sprintf (Topbar, "\015\t%s %s %s",
  882. X             p, Bar, Tcap[ME].tc_str);
  883. X        sprintf (Vbar, "%s %s", p, Tcap[ME].tc_str);
  884. X        strcpy (Botbar, Topbar);
  885. X        }
  886. X    else    {
  887. X        sprintf (Topbar, "\015\t+%s+", Bar);
  888. X        sprintf (Vbar, "|");
  889. X        strcpy (Botbar, Topbar);
  890. X        }
  891. X    return (size);
  892. X    }
  893. X
  894. X/*-------------------------------------------------------------07/01/86-+
  895. X|                                    |
  896. X|         get_rdata : get raw input and process it        |
  897. X|                                    |
  898. X+----------------------------------------------------------------------*/
  899. Xget_rdata ()
  900. X    {
  901. X    register int    i, j, n;
  902. X    int        x;        /* 0-9 index for next position */
  903. X    char        c, buf[80];
  904. X    int        dir, sel;
  905. X    int        fd = fileno (Termfp);
  906. X
  907. X    rawio (fd, &Scd);
  908. X    fputc (RETURN, Termfp);
  909. X
  910. X    if (Scroll) {            /* use scroll region */
  911. X        sel = scroll_sel (fd);
  912. X        i = 0; goto eos;
  913. X        }
  914. X    move_many (Dircount+1-Topsel, UP); /* back to top */
  915. X    move_many (13, ND);
  916. X
  917. X    for (i=Topsel; ;) {        /* selection loop */
  918. X        read (fd, &c, 1);
  919. X        n = i;  x = 0;
  920. X        switch (c & 0x7f) {
  921. X            case '9': case '8': case '7': case '6':    case '5':
  922. X            case '4': case '3': case '2': case '1': case '0':
  923. X                    x = (c & 0x7f) - '0';
  924. X                    if (x >= Dircount) continue;
  925. X                    i = figure_dir (x, i);
  926. X                    break;
  927. X            case 'n':    i = find_idx (1, i);    /* next */
  928. X                    break;
  929. X            case 'p':    i = find_idx (-1, i);    /* prev */
  930. X                    break;
  931. X            case 'h': case 'H': case 'k': case 'K':
  932. X            case BS:    if (--i < 0) i = Dircount-1;
  933. X                    break;
  934. X            case RETURN:    sel = i; goto eos;
  935. X            case SPACE:
  936. X            default:    if (++i >= Dircount) i = 0;
  937. X                    break;
  938. X            }
  939. X        if (n == i) continue;
  940. X        if (n > i) { n = n - i;  dir = UP; }
  941. X        else { n = i - n;  dir = NL; }
  942. X
  943. X        /* move to next field */
  944. X        strcpy (buf, " \010");
  945. X        for (j=0; j<n; j++) strcat (buf, Tcap[dir].tc_str);
  946. X        strcat (buf, "-\010");
  947. X        fprintf (Termfp, "%s", buf);
  948. X        fflush (Termfp);
  949. X        }
  950. Xeos:
  951. X    move_many (Dircount-i+1, NL);
  952. X    fputc (RETURN, Termfp);
  953. X    fflush (Termfp);
  954. X    resetio (fd, &Scd);
  955. X    return (sel);
  956. X    }
  957. X
  958. X/*-------------------------------------------------------------10/09/86-+
  959. X|                                    |
  960. X|        put_line : put a line on screen to scroll        |
  961. X|                                    |
  962. X+----------------------------------------------------------------------*/
  963. Xput_line (i, lead, trail)
  964. Xint    i;                /* index to Dirstack */
  965. Xchar    *lead;                /* leading string */
  966. Xchar    *trail;                /* trailing string */
  967. X    {
  968. X    register int    n, j;
  969. X
  970. X    n = Ntab - (Arglen[i]+5+1)/Tabstop;
  971. X    for (j=0; j<n; j++) Tab[j] = '\t'; Tab[j] = EOS;
  972. X    fprintf (Termfp, "%s%s %2d: %s%s%s%s",
  973. X        lead, Vbar, i, Dirstack[i], Tab, Vbar, trail);
  974. X    }
  975. X
  976. X/*-------------------------------------------------------------10/09/86-+
  977. X|                                    |
  978. X|        scroll_sel : scroll to show the selection        |
  979. X|                                    |
  980. X+----------------------------------------------------------------------*/
  981. Xscroll_sel (fd)
  982. Xint    fd;
  983. X    {
  984. X    register int    idx;        /* index to Dirstack of top element */
  985. X    register int    target;        /* target index */
  986. X    register int    move_cnt;    /* # of up/down to move */
  987. X    int        topline;    /* top line number of the box */
  988. X    int        botline;    /* bottom line # of the box */
  989. X    int        ld;        /* last digit (0-9) */
  990. X    char        c;
  991. X
  992. X    /* find out where is the cursor and define the scroll region
  993. X       accordingly. Note this should be done AFTER the directory
  994. X       stack dislpayed since you do not know where the original
  995. X       screen boundaries defined to be. */
  996. X
  997. X    botline = get_curline (fd) - 2;
  998. X    topline = botline - Dircount + 1;        /* define region */
  999. X    fprintf (Termfp, "%s%s%s", Tcap[SC].tc_str,
  1000. X         cs_define (topline, botline), Tcap[RC].tc_str);
  1001. X
  1002. X    move_many (Dircount+1, UP);
  1003. X    move_many (13, ND);
  1004. X
  1005. X    for (idx=Topsel, move_cnt=1; ; move_cnt=1) {
  1006. X        read (fd, &c, 1);    /* get user key stroke */
  1007. X        c &= 0x7F;
  1008. X        switch (c) {
  1009. X            case RETURN:
  1010. X            goto eofor;
  1011. X
  1012. X            case 'n':
  1013. X            target = find_idx (1, idx);
  1014. X            goto move;
  1015. X            case 'p':
  1016. X            target = find_idx (-1, idx);
  1017. X            goto move;
  1018. X            case '9': case '8': case '7': case '6': case '5':
  1019. X            case '4': case '3': case '2': case '1': case '0':
  1020. X            ld = c - '0';
  1021. X            if (ld >= Dircount) continue;
  1022. X            target = idx;
  1023. X            do    {
  1024. X                if (++target >= Dircount) target = 0;
  1025. X                } while (target % 10 != ld);
  1026. Xmove:            move_cnt = target - idx;
  1027. X            if (move_cnt < 0) move_cnt += Dircount;
  1028. X            if (move_cnt > Dircount/2) {
  1029. X                move_cnt = Dircount - move_cnt;
  1030. X                goto up;
  1031. X                }
  1032. X            goto down;
  1033. X
  1034. X            case 'k': case 'K': case 'h': case 'H': case BS:
  1035. X            /* scroll down one entry */
  1036. Xup:            SAVE_CURSOR;
  1037. X            while (move_cnt-- > 0) {
  1038. X                move_many (1, SR);
  1039. X                if (--idx < 0) idx = Dircount - 1;
  1040. X                put_line (idx, "\r\t", "\r");
  1041. X                }
  1042. X            RESTORE_CURSOR;
  1043. X            break;
  1044. X
  1045. X            case 'j': case 'J': case 'l': case 'L': case SPACE:
  1046. X            default:    /* scroll up one entry */
  1047. Xdown:            SAVE_CURSOR;
  1048. X            move_many (Dircount-1, NL);
  1049. X            while (move_cnt-- > 0) {
  1050. X                move_many (1, NL);
  1051. X                put_line (idx, "\r\t", "\r");
  1052. X                if (++idx >= Dircount) idx = 0;
  1053. X                }
  1054. X            RESTORE_CURSOR;
  1055. X            break;
  1056. X            }
  1057. X        fflush (Termfp);
  1058. X        }
  1059. Xeofor:
  1060. X    /* restore scrolling region to full screen (assumed the
  1061. X       original state is so) */
  1062. X    fprintf (Termfp, "%s%s%s", Tcap[SC].tc_str,
  1063. X          cs_define (Fst_line, Line-1+Fst_line),
  1064. X         Tcap[RC].tc_str);        /* reset region */
  1065. X    fflush (Termfp);
  1066. X    return (idx);
  1067. X    }
  1068. X
  1069. X/*-------------------------------------------------------------10/09/86-+
  1070. X|                                    |
  1071. X| cs_define : return a string contains cursor scroll region definition    |
  1072. X|                                    |
  1073. X+----------------------------------------------------------------------*/
  1074. Xchar    *
  1075. Xcs_define (from, to)
  1076. Xint    from;                /* start line number */
  1077. Xint    to;                /* end line number */
  1078. X    {
  1079. X    static char    cs_buf [20];
  1080. X    static int    cs_from = 0;
  1081. X    static int    cs_to = 0;
  1082. X    static char    tc1, tc2;
  1083. X    register char    *p;
  1084. X    register int    i;
  1085. X
  1086. X    if (cs_from == 0) {
  1087. X        p = Tcap[CS].tc_str;
  1088. X        i = 0;
  1089. X        while (*p != EOS) {
  1090. X            if (strncmp (p, "%i", 2) == 0) {
  1091. X                Fst_line = 1;
  1092. X                p += 2;
  1093. X                continue;
  1094. X                }
  1095. X            if (strncmp (p, "%d", 2) == 0) {
  1096. X                if (cs_from == 0) cs_from = i;
  1097. X                else cs_to = i;
  1098. X                i += 3;        /* 3 digits reserved */
  1099. X                p += 2;
  1100. X                continue;
  1101. X                }
  1102. X            cs_buf [i++] = *p++;
  1103. X            }
  1104. X        cs_buf [i] = EOS;
  1105. X        tc1 = cs_buf [cs_from + 3];
  1106. X        tc2 = cs_buf [cs_to + 3];
  1107. X        }
  1108. X    sprintf (&cs_buf[cs_from], "%03d", from);
  1109. X    cs_buf [cs_from + 3] = tc1;
  1110. X
  1111. X    sprintf (&cs_buf[cs_to], "%03d", to);
  1112. X    cs_buf [cs_to + 3] = tc2;
  1113. X
  1114. X    return (cs_buf);
  1115. X    }
  1116. X
  1117. X/*-------------------------------------------------------------10/09/86-+
  1118. X|                                    |
  1119. X|        get_curline : get current cursor line number        |
  1120. X|                                    |
  1121. X+----------------------------------------------------------------------*/
  1122. Xget_curline (fd)
  1123. Xint    fd;
  1124. X    {
  1125. X    register int    i, gotesc = NO;
  1126. X    char        c;
  1127. X    int        line, column;
  1128. X    char        buf[80];
  1129. X
  1130. X    /* Ask terminal to report its cursor position */
  1131. X
  1132. X    fprintf (Termfp, "%s", Curpos_query); fflush (Termfp);
  1133. X    for (i=0; i<80-1; i++) {
  1134. Xloop:        read (fd, &c, 1);
  1135. X        c &= 0x7F;
  1136. X        if (gotesc == NO) {
  1137. X            if (c != ESC) goto loop;
  1138. X            gotesc = YES;
  1139. X            }
  1140. X        if ((buf[i] = c) == 'R') {     /* end of report */
  1141. X            buf[++i] = EOS;
  1142. X            break;
  1143. X            }
  1144. X        }
  1145. X    sscanf (buf, "\033[%d;%dR", &line, &column);    /* VT100 only */
  1146. X    return (line);
  1147. X    }
  1148. X
  1149. X/*-------------------------------------------------------------10/09/86-+
  1150. X|                                    |
  1151. X|     move_many : repeatedly write certain string to output device    |
  1152. X|                                    |
  1153. X+----------------------------------------------------------------------*/
  1154. Xmove_many (n, code)
  1155. Xint    n;                /* repeat count */
  1156. Xint    code;                /* index to Tcap structure */
  1157. X    {
  1158. X    register int    i;
  1159. X
  1160. X    for (i=0; i<n; i++) {
  1161. X        fprintf (Termfp, "%s", Tcap[code].tc_str);
  1162. X        }
  1163. X    fflush (Termfp);
  1164. X    }
  1165. X
  1166. X/*-------------------------------------------------------------10/14/86-+
  1167. X|                                    |
  1168. X|         my_exit : close opened terminal file then exit         |
  1169. X|                                    |
  1170. X+----------------------------------------------------------------------*/
  1171. Xmy_exit (n)
  1172. Xint    n;
  1173. X    {
  1174. X    if (Termfp) fclose (Termfp);
  1175. X    exit (n);
  1176. X    }
  1177. X
  1178. X/*-------------------------------------------------------------07/01/86-+
  1179. X|                                    |
  1180. X|   get_data : get data for terminal with no cursor addr capability    |
  1181. X|                                    |
  1182. X+----------------------------------------------------------------------*/
  1183. Xget_data ()
  1184. X    {
  1185. X    char        buf [20];
  1186. X    register int    i = 0;
  1187. X
  1188. X    printf ("Please Select [0-%d]: ", Dircount-1);
  1189. X    gets (buf);
  1190. X    if (strlen (buf)) {
  1191. X        i = atoi (buf);
  1192. X        if (i < 0 || i > Dircount-1) i = 0;
  1193. X        }
  1194. X    return (i);
  1195. X    }
  1196. X
  1197. X#define    PADDING    '\200'
  1198. X/*-------------------------------------------------------------05/10/86-+
  1199. X|                                    |
  1200. X|       tcap_init : initialize termcap data structure        |
  1201. X|                                    |
  1202. X+----------------------------------------------------------------------*/
  1203. Xtcap_init ()
  1204. X    {
  1205. X    register int    i;
  1206. X    struct    tcap    *p;
  1207. X    char        *tp;
  1208. X    unsigned int    delay;
  1209. X    int        status;
  1210. X    char        *termtype = getenv ("TERM");
  1211. X
  1212. X    if ((status = tgetent (Termcap, termtype)) != 1) {
  1213. X        if (status == 0) {
  1214. X            fprintf (stderr, "No entry for %s in termcap\r\n",
  1215. X                 termtype);
  1216. X            }
  1217. X        else    fprintf (stderr, "Can not open termcap file\r\n");
  1218. X        my_exit (1);
  1219. X        }
  1220. X
  1221. X    for (p= &Tcap[0]; strlen (p->tc_id) > 0; p++) {
  1222. X        tp = tgetstr (p, &Tsp);
  1223. X        if (tp == NULL) tp = "";     /* no such capability */
  1224. X        delay = 0;
  1225. X        while (isdigit (*tp)) {
  1226. X            delay = delay*10 + (*tp++) - '0';
  1227. X            }
  1228. X        p->tc_delay = delay;
  1229. X        p->tc_len = strlen (tp);
  1230. X        if (delay) {
  1231. X            p->tc_str = malloc (p-> tc_len + delay);
  1232. X            strcpy (p->tc_str, tp);
  1233. X            tp = p->tc_str + p->tc_len;
  1234. X            for (i=0; i<delay; i++) *tp++ = PADDING;
  1235. X            *tp = EOS;
  1236. X            p->tc_len += delay;
  1237. X            }
  1238. X        else    p->tc_str = tp;
  1239. X        Tcap_count++;
  1240. X        }
  1241. X
  1242. X    Line = tgetnum ("li");
  1243. X    tcap_special ();
  1244. X    }
  1245. X
  1246. X/*-------------------------------------------------------------07/02/86-+
  1247. X|                                    |
  1248. X|        tcap_special : special initialization            |
  1249. X|                                    |
  1250. X+----------------------------------------------------------------------*/
  1251. Xtcap_special ()
  1252. X    {
  1253. X    if (Tcap[NL].tc_len == 0) {
  1254. X        Tcap[NL].tc_str = "\n";
  1255. X        Tcap[NL].tc_delay = 0;
  1256. X        Tcap[NL].tc_len = 1;
  1257. X        }
  1258. X    }
  1259. X
  1260. X/*-------------------------------------------------------------07/01/86-+
  1261. X|                                    |
  1262. X|  get_ac : get alternate character for a given VT100 alternate char    |
  1263. X|                                    |
  1264. X+----------------------------------------------------------------------*/
  1265. Xchar
  1266. Xget_ac (c)
  1267. Xchar    c;
  1268. X    {
  1269. X    register char    *p;
  1270. X    char        oc;
  1271. X
  1272. X    if (Tcap_count == 0) tcap_init ();
  1273. X    for (p=Tcap[AC].tc_str; *p != EOS; p += 2) {
  1274. X        if (*p == c) return *(p+1);
  1275. X        }
  1276. X    switch (c) {
  1277. X        case 'j':        /* lower right corner    */
  1278. X        case 'k':        /* upper right corner    */
  1279. X        case 'l':        /* upper left corner    */
  1280. X        case 'm':  oc = '+';    /* lower left corner    */
  1281. X               break;
  1282. X        case 'q':  oc = '-';    /* horizontal bar */
  1283. X               break;
  1284. X        case 'x':  oc = '|';    /* vertical bar */
  1285. X               break;
  1286. X        default:   oc = '?';    /* bad choice */
  1287. X        }
  1288. X    return (oc);
  1289. X    }
  1290. X
  1291. X/*-------------------------------------------------------------02/18/86-+
  1292. X|                                    |
  1293. X|          figure_dir : figure out which direction to go        |
  1294. X|                                    |
  1295. X+----------------------------------------------------------------------*/
  1296. Xfigure_dir (x, i)
  1297. Xint    x;                /* target index (0-9) */
  1298. Xint    i;                /* curent index (0-Dircount) */
  1299. X    {
  1300. X    int    n;
  1301. X
  1302. X    n = i % 10;
  1303. X    if (x == n) {
  1304. X        if (i + 10 < Dircount) return (i+10);
  1305. X        }
  1306. X    if (x > n) {
  1307. X        if (i - n + x < Dircount) return (i - n + x);
  1308. X        }
  1309. X    else    {
  1310. X        if (i - n + x + 10 < Dircount) return (i - n + x + 10);
  1311. X        }
  1312. X
  1313. X    return (x);
  1314. X    }
  1315. X
  1316. X/*-------------------------------------------------------------02/17/86-+
  1317. X|                                    |
  1318. X|         cp_ptr : copy all the argv pointers to Dirstack        |
  1319. X|                                    |
  1320. X+----------------------------------------------------------------------*/
  1321. Xcp_ptr (argc, argv)
  1322. Xint    argc;
  1323. Xchar    **argv;
  1324. X    {
  1325. X    register int    i, j;
  1326. X    int        n;
  1327. X    int        size = 0;
  1328. X
  1329. X    for (j=0, i=Sno; i<argc; i++) {
  1330. X        if (j >= Maxdir) {
  1331. X            fprintf (stderr, "Max %d entries, extra ignored\n",
  1332. X                 Maxdir);
  1333. X            fflush (stderr);
  1334. X            break;
  1335. X            }
  1336. X        Dirstack[j] = argv[i];            /* save start addr */
  1337. X        Arglen[j++] = n = strlen (argv[i]);    /* and length */
  1338. X        if (n > size) size = n;
  1339. X        }
  1340. X    Dircount = j;
  1341. X    return (size);            /* return the longest length */
  1342. X    }
  1343. X
  1344. X/*-------------------------------------------------------------02/17/86-+
  1345. X|                                    |
  1346. X|            make_argv : make an argument list            |
  1347. X|                                    |
  1348. X+----------------------------------------------------------------------*/
  1349. Xmake_argv ()
  1350. X    {
  1351. X    char        *p = Stack;
  1352. X    char        *op = Stack;    /* old pointer */
  1353. X    char        c;
  1354. X    register int    i = 0;
  1355. X    int        size = 0;
  1356. X    int        n;
  1357. X
  1358. X    gets (Stack);
  1359. X    while ((c = *p) != NEWLINE && c != EOS) {
  1360. X        if (c == SPACE) {
  1361. X            *p = EOS;
  1362. X            Dirstack[i] = op;
  1363. X            Arglen[i++] = n = p - op;
  1364. X            if (n > size) size = n;
  1365. X            op = p+1;
  1366. X            }
  1367. X        p++;
  1368. X        }
  1369. X    if (i > Maxdir) {
  1370. X        fprintf (stderr, "Max %d entries, extra ignored\n", Maxdir);
  1371. X        fflush (stderr);
  1372. X        i = Maxdir;
  1373. X        }
  1374. X    Dircount = i;
  1375. X    return (size);
  1376. X    }
  1377. X/*-------------------------------------------------------------10/14/86-+
  1378. X|                                    |
  1379. X|        find_idx : find next/prev index from Str_idx array        |
  1380. X|                                    |
  1381. X+----------------------------------------------------------------------*/
  1382. Xfind_idx (dir, n)
  1383. Xint    dir;                /* direction: 1=next, -1=prev */
  1384. Xint    n;                /* current index */
  1385. X    {
  1386. X    register int    i;
  1387. X
  1388. X    for (i=0; i<Str_total; i++) {
  1389. X        if (Str_idx[i] == n) {        /* found current, locate next */
  1390. X            i += dir;
  1391. X            if (i == Str_total) i = 0;
  1392. X            if (i < 0) i = Str_total - 1;
  1393. X            return (Str_idx[i]);
  1394. X            }
  1395. X        }
  1396. X    return (n);
  1397. X    }
  1398. X
  1399. X/*------------------------------------------------------------07/12/84--+
  1400. X|                                    |
  1401. X|    proc_arg : routine to process command arguments (options)    |
  1402. X|                                    |
  1403. X+----------------------------------------------------------------------*/
  1404. Xproc_arg (argc, argv)
  1405. Xint    argc;
  1406. Xchar    **argv;
  1407. X    {
  1408. X    register int    i;
  1409. X    register int    n;
  1410. X    char        *p;
  1411. X
  1412. X    p = getenv ("TABSTOP");
  1413. X    if (p != NULL) {        /* set tabstop to n (default 8) */
  1414. X        n = atoi (p);
  1415. X        if (n > 0) Tabstop = n;
  1416. X        }
  1417. X    for (n=i=0; i<argc; i++) {
  1418. X        if (argv[i][0] != '-') {
  1419. X            n++;        /* count non-option argument */
  1420. X            continue;
  1421. X            }
  1422. X        Sno++;
  1423. X        switch (argv[i][1]) {
  1424. X            when 's':    p = &argv[i][2];
  1425. X                if ((Schlen = strlen (p)) == 0) Select = YES;
  1426. X                else Search_string = p;
  1427. X
  1428. X            when 'r':    tcap_init ();
  1429. X                if (Tcap[SC].tc_len != 0 &&
  1430. X                    Tcap[RC].tc_len != 0 &&
  1431. X                    Tcap[CS].tc_len != 0) Scroll = YES;
  1432. X
  1433. X            when 'b':    box_style (argv[i][2]);
  1434. X
  1435. X            when 'v':    printf ("%s\n%s\n", Version, Author);
  1436. X                my_exit (0);
  1437. X
  1438. X            otherwise:    Sno--;        /* dont count */
  1439. X            }
  1440. X        }
  1441. X    return (n);
  1442. X    }
  1443. X
  1444. X/*-------------------------------------------------------------10/14/86-+
  1445. X|                                    |
  1446. X|   search : find string in dir stack and exit or return found index    |
  1447. X|                                    |
  1448. X+----------------------------------------------------------------------*/
  1449. Xsearch ()
  1450. X    {
  1451. X    register int    i, j;
  1452. X    register char    *p;
  1453. X    int        len;
  1454. X    int        sel;
  1455. X
  1456. X    /* If argument starts with a number, it will be used as index to
  1457. X       directory stack.  If not, it will be used as string to search */
  1458. X
  1459. X    sel = atoi (Search_string);
  1460. X    if (0 < sel && sel < Dircount) {     /* number used as index */
  1461. Xmatch:        puts (Dirstack[sel]);
  1462. X        my_exit (sel);
  1463. X        }
  1464. X    for (Str_total=i=0, sel = -1; i<Dircount; i++) {
  1465. X        len = Arglen[i];
  1466. X        p = Dirstack[i];
  1467. X        for (j=0; j<=len-Schlen; j++) {
  1468. X            if (strncmp (Search_string, p+j, Schlen) == 0) {
  1469. X                Str_idx[Str_total++] = i;
  1470. X                if (sel == -1) sel = i;
  1471. X                break;
  1472. X                }
  1473. X            }
  1474. X        }
  1475. X    if (Str_total == 1) goto match;
  1476. X    Select = YES;
  1477. X    return ((sel == -1) ? 0 : sel); /* more than one, stay around */
  1478. X    }
  1479. X
  1480. X/*-------------------------------------------------------------10/14/86-+
  1481. X|                                    |
  1482. X|            box_style : select box style            |
  1483. X|                                    |
  1484. X+----------------------------------------------------------------------*/
  1485. Xbox_style (style)
  1486. Xchar    style;                /* style */
  1487. X    {
  1488. X    switch (style) {
  1489. X        when 'h':    Boxstyle = BOX_HIGHLITE;
  1490. X        when 'r':    Boxstyle = BOX_REVERSE;
  1491. X        when 'g':    Boxstyle = BOX_GRAPH;
  1492. X        otherwise:    Boxstyle = BOX_DASH;
  1493. X        }
  1494. X    }
  1495. X
  1496. Xint        Old_flags;
  1497. Xint        Pseudo = -1;        /* 0/1 = normal/pseudo terminal */
  1498. X/*------------------------------------------------------------07/10/84--+
  1499. X|                                    |
  1500. X|       rawio : oepn terminal in RAW mode without ECHO        |
  1501. X|                                    |
  1502. X+----------------------------------------------------------------------*/
  1503. Xrawio (fd, mp)
  1504. Xint        fd;            /* file descriptor */
  1505. Xstruct    sgttyb    *mp;            /* ptr to mode structure */
  1506. X    {
  1507. X    char    *tname = (char *) ttyname (fileno(stdout)) + 8;
  1508. X                    /* /dev/ttypxxx    */
  1509. X                    /* 012345678    */
  1510. X
  1511. X    if (*tname == 'p' || *tname == 'q' || *tname == 'r') {
  1512. X        /* pseudo terminal, delay a while so that output will
  1513. X           drain...   */
  1514. X        Pseudo = YES;
  1515. X        sleep (1);
  1516. X        }
  1517. X    else    Pseudo = NO;
  1518. X
  1519. X    ioctl (fd, TIOCGETP, mp);
  1520. X    Old_flags = mp-> sg_flags;    /* save old setting */
  1521. X    mp-> sg_flags |= RAW;
  1522. X    mp-> sg_flags &= ~ECHO;
  1523. X    ioctl (fd, TIOCSETP, mp);
  1524. X    }
  1525. X
  1526. X/*------------------------------------------------------------07/10/84--+
  1527. X|                                    |
  1528. X|    resetio : close terminal and restore original setting        |
  1529. X|                                    |
  1530. X+----------------------------------------------------------------------*/
  1531. Xresetio (fd, mp)
  1532. Xint        fd;            /* file descriptor */
  1533. Xstruct    sgttyb    *mp;            /* ptr to old setting */
  1534. X    {
  1535. X    if (Pseudo) sleep (1);
  1536. X
  1537. X    mp-> sg_flags = Old_flags;
  1538. X    ioctl (fd, TIOCSETP, mp);    /* restore original setting */
  1539. X    }
  1540. SHAR_EOF
  1541. if test 23978 -ne "`wc -c < 'shdir.c'`"
  1542. then
  1543.     echo shar: error transmitting "'shdir.c'" '(should have been 23978 characters)'
  1544. fi
  1545. fi # end of overwriting check
  1546. #    End of shell archive
  1547. exit 0
  1548.